import datetime
import re
import secrets
import string
import sys
from functools import wraps

from flask import Blueprint
from flask import session, request
import hashlib

from common.exceptions import AuthorizationFailed, UnKnownUserException
from model.book import BookSpaceModel
from model.email_model import EmailService
from model.team import TeamSpaceModel
from model.user import UserModal
from util.args_validate import ArgsValidate
from util.auth_validate import auth_validate
from util.db import Cursor
from flask_restx import reqparse, Resource, Api
from flask_jwt_extended import (
    create_access_token, create_refresh_token, jwt_required, get_jwt_identity, get_jwt
)
from util.login_validate import login_validate

app_wiki = Blueprint(name="app_wiki", import_name=__name__, url_prefix='/api/space')


class TeamSpace:
    """团队空间的操作"""

    @staticmethod
    @app_wiki.route('/inviteUser', methods=['GET'])
    @jwt_required(locations=["query_string"])
    def get_invite_user():
        user_info = get_jwt_identity()
        user_id = user_info.get('user_id')
        team_id = user_info.get('team_id')
        role = user_info.get('role')
        create_time = datetime.datetime.now()
        with Cursor() as cursor:
            sql = """select id from yugong_role_team where user_id=%s and team_id=%s"""
            cursor.execute(sql, [user_id, team_id])
            res = cursor.fetchall()
            if res:
                return '您已加入过此团队，无需重复加入', 200
            sql = """insert into yugong_role_team (user_id, team_id, role, create_time, created, joind) values (%s, %s, %s, %s, %s, %s)"""
            cursor.execute(sql, [user_id, team_id, role, create_time, 0, 1])

        return '恭喜！您已成功加入此团队', 200

    @staticmethod
    @app_wiki.route('/inviteUser', methods=['POST'])
    @login_validate
    def post_invite_user():
        parser = reqparse.RequestParser()
        parser.add_argument('email', type=str, help='邮箱', nullable=False, required=True, trim=True)
        parser.add_argument('role', type=str, help='角色', required=True, trim=True)
        parser.add_argument('teamId', type=int, help='团队ID', required=True, trim=True)

        args = parser.parse_args(strict=False)
        email = args.get('email')
        new_user_role = args.get('role')
        team_id = args.get('teamId')
        role = TeamSpaceModel.get_team_role(id=team_id, id_type='team')
        if not role or role != 'admin':
            raise AuthorizationFailed('抱歉, 仅管理员可邀请协作成员')
        with Cursor() as cursor:
            sql = """select id from yugong_user where email=%s"""
            cursor.execute(sql, [email])
            res = cursor.fetchall()
        if not res:
            raise UnKnownUserException('您邀请的用户尚未注册，请确认用户邮箱是否正确')
        invited_user_id =  res[0]['id']
        name = TeamSpaceModel(team_id).name
        access_token = create_access_token(identity={'user_id': invited_user_id, 'role': new_user_role, 'team_id': team_id})
        if sys.platform == 'win32':
            url = 'http://127.0.0.1:5005/api/space/inviteUser?jwt={}'.format(access_token)
        else:
            url = 'https://www.yugongcoding.com/api/space/inviteUser?jwt={}'.format(access_token)
        inviter = UserModal().username
        EmailService.send_email_invite(email=email, url=url, inviter=inviter, team_name=name)
        return {"code": 0, "errMsg": "获取成功", "data": None}, 200

    @staticmethod
    @app_wiki.route('/authOptions', methods=['GET'])
    @login_validate
    def get_auth_options():
        parser = reqparse.RequestParser()
        parser.add_argument('id', type=int, help='资源ID', nullable=False, required=True, trim=True)
        parser.add_argument('resourceType', type=str, help='资源类型', required=True, trim=True)
        args = parser.parse_args(strict=False)
        id = args.get('id')
        resource_type = args.get('resourceType')
        with Cursor() as cursor:
            if resource_type == 'team':
                sql = """select auth from yugong_team where id=%s"""
            if resource_type == 'book':
                sql = """select auth from yugong_book where id=%s"""
            if resource_type == 'article':
                sql = """select auth from yugong_article where id=%s"""
            cursor.execute(sql, [id])
            res = cursor.fetchall()
            auth = res[0]['auth']
            if auth == 0:
                data = [{
                        'label': '公开可见',
                        'value': 0
                      },{
                        'label': '私人可见',
                        'value': 1
                      },{
                        'label': '空间成员可见',
                        'value': 2
                      }
                  ]
            if auth == 1:
                data = [{
                        'label': '私人可见',
                        'value': 1
                      }
                  ]
            if auth == 2:
                data = [{
                        'label': '私人可见',
                        'value': 1
                      },{
                        'label': '空间成员可见',
                        'value': 2
                      }
                  ]
        return {"code": 0, "errMsg": "获取成功", "data": data}, 200

    @staticmethod
    @app_wiki.route('/teamSpace', methods=['POST'])
    @login_validate
    def post_team_space():
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str, help='团队名称', nullable=False, required=True, trim=True)
        parser.add_argument('category', type=str, help='分类', trim=True)
        parser.add_argument('description', type=str, help='团队描述', trim=True, required=True, )
        parser.add_argument('auth', type=int, help='可见范围', required=True, )
        args = parser.parse_args(strict=False)
        auth = args.get('auth')
        teamName = args.get('name')
        category = args.get('category')
        description = args.get('description')
        user_id = session.get('user_id')
        # 鉴权
        auth_validate(operation='create', resource='team', user_id=user_id)
        create_time = datetime.datetime.now()
        with Cursor() as cursor:
            sql = """insert into yugong_team (`name`, `category`,
            `description`, `user_id`, `auth`, `create_time`) values (%s, %s, %s, %s, %s, %s)"""
            cursor.execute(sql, [teamName, category, description, user_id, auth, create_time])
            this_id = cursor.lastrowid
            sql = """insert into yugong_role_team (`user_id`, `team_id`, `create_time`, `role`) values (%s, %s, %s, %s)"""
            cursor.execute(sql, [user_id, this_id, create_time, 'admin'])
        return {"code": 0, "errMsg": "创建成功", "data": []}, 200

    @staticmethod
    @app_wiki.route('/teamSpace', methods=['GET'])
    @login_validate
    def get_team_space():
        user_id = session.get('user_id')
        # 鉴权
        auth_validate(operation='read', resource='team', user_id=user_id)
        with Cursor() as cursor:
            sql = """select * from (select * from `yugong_team` where id in (select team_id from yugong_role_team where user_id=%s)) as a
                    LEFT JOIN 
                    (SELECT username, id FROM yugong_user) as b
                    ON a.user_id=b.id"""
            cursor.execute(sql, [user_id])
            res = cursor.fetchall()
            for item in res:
                item['create_time'] = item['create_time'].strftime('%Y-%m-%d %H:%M:%S')
                if item['auth'] == 0:
                    item['auth_cn'] = '公开可见'
                if item['auth'] == 1:
                    item['auth_cn'] = '私人可见'
                if item['auth'] == 2:
                    item['auth_cn'] = '空间成员可见'
        return {"code": 0, "errMsg": "获取成功", "data": res}, 200

    @staticmethod
    @app_wiki.route('/teamSpace', methods=['PATCH'])
    @login_validate
    def patch_team_space():
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str, help='团队名称', nullable=False, required=True, trim=True)
        parser.add_argument('category', type=str, help='分类', trim=True)
        parser.add_argument('description', type=str, help='团队描述', trim=True, required=True, )
        parser.add_argument('auth', type=int, help='可见范围', required=True, )
        parser.add_argument('id', type=int, help='团队ID', required=True, )
        args = parser.parse_args(strict=True)
        auth = args.get('auth')
        name = args.get('name')
        category = args.get('category')
        description = args.get('description')
        user_id = session.get('user_id')
        team_id = args.get('id')
        # 鉴权
        team_role = TeamSpaceModel.get_team_role(id=team_id, id_type='team')
        if team_role == 'reader':
            raise AuthorizationFailed()
        with Cursor() as cursor:
            sql = """update `yugong_team` set name=%s, category=%s, description=%s, auth=%s
             where `id`=%s"""
            cursor.execute(sql, [name, category, description, auth,  team_id])
        return {"code": 0, "errMsg": "修改成功", "data": None}, 200

    @staticmethod
    @app_wiki.route('/teamSpace', methods=['DELETE'])
    @login_validate
    def delete_team_space():
        parser = reqparse.RequestParser()
        parser.add_argument('teamId', type=int, help='知识库ID', trim=True)
        args = parser.parse_args(strict=True)
        team_id = args.get('teamId')
        # 鉴权
        team_role = TeamSpaceModel.get_team_role(id=team_id, id_type='team')
        if team_role != 'admin':
            raise AuthorizationFailed()
        with Cursor() as cursor:
            sql = """delete from `yugong_team` where `id`=%s"""
            cursor.execute(sql, [team_id])
        return {"code": 0, "errMsg": "删除成功", "data": None}, 200


class BookSpace:

    @staticmethod
    @app_wiki.route('/bookSpace', methods=['POST'])
    @login_validate
    def post_book_pace():
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str, help='团队名称', nullable=False, required=True, trim=True)
        parser.add_argument('category', type=str, help='分类', trim=True)
        parser.add_argument('description', type=str, help='团队描述', trim=True)
        parser.add_argument('team', type=int, help='团队ID', trim=True)
        parser.add_argument('auth', type=int, help='可见范围', required=True, )

        args = parser.parse_args(strict=False)
        auth = args.get('auth')
        teamName = args.get('name')
        category = args.get('category')
        description = args.get('description')
        team = args.get('team')
        user_id = session.get('user_id')
        # 鉴权
        auth_validate(operation='create', resource='book', user_id=user_id)
        create_time = datetime.datetime.now()
        with Cursor() as cursor:
            sql = """insert into yugong_book (`name`, `category`,
            `description`, `team_id`, `auth`, `user_id`, `create_time`) values (%s, %s, %s, %s, %s, %s, %s)"""
            cursor.execute(sql, [teamName, category, description, team, auth, user_id, create_time])
            this_id = cursor.lastrowid
        return {"code": 0, "errMsg": "创建成功", "data": []}, 200

    @staticmethod
    @app_wiki.route('/bookSpace', methods=['GET'])
    def get_book_space():
        parser = reqparse.RequestParser()
        parser.add_argument('teamId', type=int, help='团队ID', trim=True)
        args = parser.parse_args(strict=True)
        team_id = args.get('teamId')
        data = BookSpaceModel.get_book_space_with_login(team_id)
        return {"code": 0, "errMsg": "获取成功", "data": data}, 200

    @staticmethod
    @app_wiki.route('/bookSpace', methods=['PATCH'])
    @login_validate
    def patch_book_space():
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str, help='团队名称', nullable=False, required=True, trim=True)
        parser.add_argument('category', type=str, help='分类', trim=True)
        parser.add_argument('description', type=str, help='团队描述', trim=True)
        parser.add_argument('team', type=int, help='团队ID', trim=True)
        parser.add_argument('auth', type=int, help='可见范围', required=True, )
        parser.add_argument('id', type=int, help='BOOK ID', required=True, )

        args = parser.parse_args(strict=False)
        auth = args.get('auth')
        name = args.get('name')
        category = args.get('category')
        description = args.get('description')
        id = args.get('id')
        user_id = session.get('user_id')
        # 鉴权
        team_role = TeamSpaceModel.get_team_role(id=id, id_type='book')
        if not team_role or team_role == 'reader':
            raise AuthorizationFailed()
        with Cursor() as cursor:
            sql = """update `yugong_book` set name=%s, category=%s, description=%s, auth=%s
                 where `id`=%s"""
            cursor.execute(sql, [name, category, description, auth, id])
        return {"code": 0, "errMsg": "修改成功", "data": None}, 200

    @staticmethod
    @app_wiki.route('/bookSpace', methods=['DELETE'])
    @login_validate
    def delete_book_space():
        parser = reqparse.RequestParser()
        parser.add_argument('bookId', type=int, help='知识库ID', trim=True)
        args = parser.parse_args(strict=True)
        book_id = args.get('bookId')
        # 鉴权
        team_role = TeamSpaceModel.get_team_role(id=book_id, id_type='book')
        if team_role != 'admin':
            raise AuthorizationFailed()
        with Cursor() as cursor:
            sql = """delete from `yugong_book` where `id`=%s"""
            cursor.execute(sql, [book_id])
        return {"code": 0, "errMsg": "删除成功", "data": None}, 200



